package service

import (
	"choujiang/common/models"
	"time"
	"choujiang/common/db"
	"choujiang/common/consts"
	"fmt"
	"strconv"
	"choujiang/common/utils"
)

func CreateNewOrder(Gid int64, Gnum int64, uniqueId, realName, phone, address string) *utils.ErrorType {
	user := model.GetUserByUniqueId(uniqueId) //用户
	//用户未找到
	if user == nil {
		return consts.ErrUserNotFound
	}
	goods := model.GetGoodsById(Gid)
	if goods == nil {
		return consts.ErrGoodsNotFound
	}
	//开启事务
	session := db.MysqlEngine.NewSession()
	defer session.Close()
	err := session.Begin()
	if err != nil {
		fmt.Printf("OrderAdd transaction err:", err)
	}
	//行锁锁定goods表
	result, err := session.QueryString("select * from goods where id = ? for update", Gid)
	//商品未找到
	if err != nil {
		fmt.Printf("error info is:", err)
		session.Commit()
		return consts.ErrGoodsNotFound
	}
	//商品库存不足
	queryNum, _ := strconv.ParseInt(result[0]["num"], 10, 64)
	if queryNum < Gnum {
		session.Commit()
		return consts.ErrGoodsNotEnough
	}
	//行锁锁定user_extra
	reUser, err := session.QueryString("select * from user_extra where user_id = ? for update", user.Id)
	if err != nil {
		fmt.Printf("error info is:", err)
		session.Commit()
		return consts.ErrUserNotFound
	}
	//用户余额不足
	userPoint, _ := strconv.ParseFloat(reUser[0]["balance"], 64)
	rePrice, _ := strconv.ParseFloat(result[0]["price"], 64)
	if userPoint < rePrice*float64(Gnum) {
		session.Commit()
		return consts.ErrBalanceNotEnough
	}

	currentTime := time.Now().Unix()
	order := new(model.Orders)

	order.GoodsId = Gid
	order.OrderSn = utils.GenOrderSn(user.UniqueId, strconv.FormatInt(time.Now().Unix(), 10))
	order.GoodsNum = Gnum
	order.UserId = user.Id
	order.Cost = rePrice * float64(Gnum)
	order.PayType = model.POINT_PAY
	order.OrderStatus = model.ORDER_STATUS_PAY
	order.CreatedAt = currentTime
	order.UpdatedAt = currentTime
	order.PayAt = currentTime
	order.Phone = phone
	order.Receiver = realName
	order.Address = address
	order.OrderType = 1
	_, err = session.Insert(order)
	if err != nil {
		fmt.Printf("error info is:", err)
		session.Rollback()
		session.Commit()
		return consts.ErrInterval
	}

	costPoint := rePrice * float64(Gnum)
	_, err = session.Exec("update user_extra set balance = balance - ? where user_id = ?", costPoint, user.Id)
	if err != nil {
		fmt.Printf("error info is:", err)
		session.Rollback()
		session.Commit()
		return consts.ErrInterval
	}
	db.Mgo.WriteCoinsLog(user.Id, CONINS_EXPEND_COLLECT, user.NickName, goods.Title, "购买"+goods.Title, costPoint)

	_, err = session.Exec("update goods set num = num - ? where id = ?", Gnum, Gid)
	if err != nil {
		fmt.Printf("error info is:", err)
		session.Rollback()
		session.Commit()
		return consts.ErrInterval
	}

	err = session.Commit()
	if err != nil {
		fmt.Printf("error info is:", err)
		return consts.ErrInterval
	}

	return nil
}

//兑换红包
func ExchangePackage(Gnum int64, uniqueId string, goods *model.Goods) *utils.ErrorType {
	user := model.GetUserByUniqueId(uniqueId) //用户
	//用户未找到
	if user == nil {
		return consts.ErrUserNotFound
	}
	userExtra := model.GetUserExtraByUid(user.Id) //额外信息
	if userExtra == nil {
		return consts.ErrUserNotFound
	}
	//开启事务
	session := db.MysqlEngine.NewSession()
	defer session.Close()
	err := session.Begin()
	if err != nil {
		fmt.Printf("ExchangePackage transaction err:", err)
	}
	//行锁锁定user_extra
	reUser, err := session.QueryString("select * from user_extra where user_id = ? for update", user.Id)
	if err != nil {
		fmt.Printf("error info is:", err)
		session.Commit()
		return consts.ErrUserNotFound
	}
	uPoint, _ := strconv.ParseInt(reUser[0]["point"], 10, 64) //用户余额
	cPoint := goods.Price * Gnum                              //消耗金币
	aBalance := Gnum * goods.Balance                          //兑换的红包总额
	if cPoint > uPoint {
		session.Commit()
		return consts.ErrBalanceNotEnough
	}

	_, err = session.Exec("update user_extra set point = point - ?, balance = balance + ? where user_id = ?", cPoint, aBalance, user.Id)
	if err != nil {
		fmt.Printf("error info is:", err)
		session.Rollback()
		session.Commit()
		return consts.ErrInterval
	}

	err = session.Commit()
	if err != nil {
		fmt.Printf("error info is:", err)
		return consts.ErrInterval
	}

	return nil
}

func GetUserOrders(user *model.User) []model.Orders {
	orders := make([]model.Orders, 0)
	db.MysqlEngine.Select("orders.id, orders.goods_id, orders.receiver, orders.phone, orders.address, orders.cost, orders.pay_at").Where("orders.user_id=? and orders.order_status=? and orders.order_type=?", user.Id, 1, 1).Desc("orders.created_at").Find(&orders)
	for i := 0; i < len(orders); i++ {
		orders[i].GoodsInfo = model.GetGoodsById(orders[i].GoodsId)
		orders[i].GoodsInfo.Cover = utils.AddPrefix(orders[i].GoodsInfo.Cover)
	}
	return orders
}
